package com.cly.utils;

import com.cly.entity.Message;
import com.cly.enums.MessageType;
import com.cly.vo.OnlineUserVo;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * WebSocket工具类
 *
 * @author by 春风能解释
 * <p>
 * 2025/2/14
 */
@Slf4j
public class WebSocketUtils {
    /**
     * 用户信息
     */
    private static final Map<String, WebSocketSession> USERS = new ConcurrentHashMap<>();
    /**
     * 用户信息
     */
    private static final Map<String, OnlineUserVo> USER_INFO = new ConcurrentHashMap<>();

    /**
     * 添加用户信息
     *
     * @param key     键
     * @param session 值
     * @param user    用户信息
     */
    public static void put(String key, WebSocketSession session, OnlineUserVo user) {
        USERS.put(key, session);
        USER_INFO.put(key, user);
    }

    /**
     * 移除用户信息
     *
     * @param key 键
     */
    public static void remove(String key) {
        USERS.remove(key);
        USER_INFO.remove(key);
    }


    /**
     * 获取用户信息
     *
     * @return 用户信息
     */
    public static Collection<WebSocketSession> getUsers() {
        return USERS.values();
    }

    /**
     * 获取用户信息
     *
     * @return 用户信息
     */
    public static Collection<OnlineUserVo> getUserInfo() {
        return USER_INFO.values();
    }

    /**
     * 向多人发送消息
     *
     * @param ids     用户ID
     * @param message 消息
     */
    public static <T> void sendMessageToUsers(Collection<String> ids, T message) {
        ids.forEach(id -> sendMessageToUser(id, message));
    }

    /**
     * 向所有用户发送消息
     *
     * @param message 消息
     * @param <T>     消息类型
     */
    public static <T> void sendMessageToAllUsers(T message) {
        getUsers().forEach(session -> sendMessageToUser(session, message));
    }

    /**
     * 发送在线用户
     */
    public static void sendOnlineUsers() {
        sendMessageToAllUsers(new Message()
                .setType(MessageType.USER_LOGIN.getValue())
                .setContent(USER_INFO));
    }


    /**
     * 发送消息
     *
     * @param key     用户ID
     * @param message 消息
     * @param <T>     消息类型
     * @return ID
     */
    public static <T> String sendMessageToUser(String key, T message) {
        return sendMessageToUser(USERS.get(key), message);
    }

    /**
     * 发送消息
     *
     * @param message 消息
     * @return ID
     */
    public static String sendMessageToUser(Message message) {
        if (Objects.isNull(message.getTo())) {
            return null;
        }
        WebSocketSession webSocketSession = USERS.get(message.getTo().toString());
        sendMessageToUser(webSocketSession, message);
        return webSocketSession.getId();
    }

    /**
     * 发送消息
     *
     * @param session 会话
     * @param message 消息
     * @param <T>     消息类型
     * @return ID
     */
    @SneakyThrows
    public static <T> String sendMessageToUser(WebSocketSession session, T message) {
        if (Objects.isNull(session)) {
            log.info("\n[你已离线]");
            return null;
        }
        log.info("\n 接收到客户端消息 - {}", message);
        session.sendMessage(new TextMessage(JsonSerializeUtils.serialize(message)));
        return session.getId();
    }

}
